package com.is2.patchinglife.manager;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Locale;

import com.is2.patchinglife.listener.AccelerometerListener;
import com.is2.patchinglife.listener.LightListener;
import com.is2.patchinglife.listener.ProximityListener;
import com.is2.patchinglife.listener.TelephonyListener;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;

public class ListenerManager {
	
	public static SensorManager sensor_manager = null;
	public static Hashtable<Integer, SensorEventListener> sensorListeners = null;
	
	private static TelephonyManager telephonyManager = null;
	public static Hashtable<Integer, TelephonyListener> telephonyListeners = null;
	
	private static Hashtable<Integer,String> sensTypes = null;		// supported sensors [int to String]
	private static Hashtable<Integer,String> telTypes = null;		// supported telephony [int to String]
	
	/** Private constructor **/
	private ListenerManager(){}

	/** SINGLETON: return the 'listeners' hash_table **/
	public static void initialize(Context _context){
		
		// set supported types
		if(sensTypes == null){
			sensTypes = new Hashtable<Integer,String>();
			sensTypes.put(Sensor.TYPE_ACCELEROMETER,"Accelerometer");
			sensTypes.put(Sensor.TYPE_LIGHT,"Light");
			sensTypes.put(Sensor.TYPE_PROXIMITY,"Proximity");
		}
		
		// set supported telephony
		if(telTypes == null){
			telTypes = new Hashtable<Integer,String>();
			telTypes.put(PhoneStateListener.LISTEN_CALL_STATE,"Telephony");
		}
		
		// set sensor manager
		if (sensorListeners == null){
			sensor_manager = (SensorManager) _context.getSystemService(Context.SENSOR_SERVICE);
			sensorListeners = new Hashtable<Integer, SensorEventListener>();
		}
		
		// set telephony manager
		if(telephonyManager == null){
			telephonyManager = (TelephonyManager)_context.getSystemService(Context.TELEPHONY_SERVICE);
			telephonyListeners = new Hashtable<Integer, TelephonyListener>();
		}
	}
	
	

	/** Get sensor type [int to String] **/
	public static String getSensorType(int _type){
		try{
			return sensTypes.get(_type);
		}catch(NullPointerException e){
			return null;
		}
	}
	
	
	/** Get telephony type [int to String] **/
		public static String getTelephonyType(int _type){
			try{
				return telTypes.get(_type);
			}catch(NullPointerException e){
				return null;
			}
		}
	
		
		
	/** Get sensor manager **/
	public static SensorManager getSensorManager(){return sensor_manager;}
	
	
	/** Get telephony manager **/
	public static SensorManager getTelephonyManager(){return sensor_manager;}

	
	
	
	/** Get listener list **/
	public static Hashtable<Integer, SensorEventListener> getHashSensorListners(){return sensorListeners;}
	
	/** Get telephony list **/
	public static Hashtable<Integer, TelephonyListener> getHashTelephonyListners(){return telephonyListeners;}
	
	
	
	
	/** Get sensor listener [WITH STRING KEY] **/
	public static SensorEventListener getSensorListener(String _key){
		try{
			return sensorListeners.get(_key);
		}catch(NullPointerException e){			// not in list
			return null;
		}
	}
	
	
	/** Get telephony listener [WITH STRING KEY] **/
	public static TelephonyListener getTelephonyListener(String _key){
		try{
			return telephonyListeners.get(_key);
		}catch(NullPointerException e){			// not in list
			return null;
		}
	}
	
	
	
	/** Add sensor listener **/
	public static void addSensorListener(int[] _keyList){
		
		// multiple sensor registration is possible
		for(int key:_keyList){
			
			SensorEventListener ltnr = null;
			
			// do not initialize inhibited sensors
			switch(key){
			case Sensor.TYPE_ACCELEROMETER:
				if(!LocalDataManager.getInhibited("accelerometer")){
					ltnr = new AccelerometerListener();
				}
				break;
			case Sensor.TYPE_PROXIMITY:
				if(!LocalDataManager.getInhibited("proximity")){
					ltnr = new ProximityListener();
				}
				break;
			case Sensor.TYPE_LIGHT:
				if(!LocalDataManager.getInhibited("light")){
					ltnr = new LightListener();
				}
				break;
			default:
				break;
			}
			
			// register selected listener
			if(ltnr!=null){
				List<Sensor> sens_list = sensor_manager.getSensorList(key);
				if(sens_list!=null && !sens_list.isEmpty()){
					Sensor first_sensor = sens_list.get(0);
					sensor_manager.registerListener(ltnr, first_sensor, SensorManager.SENSOR_DELAY_UI);
					sensorListeners.put(key, ltnr);
				}else{
					LocalDataManager.setInhibited(sensTypes.get(key).toLowerCase(Locale.ENGLISH),true);
				}
			}else
				Log.e("ListenerManager","addSensorListener: Not valid sensor type.");
		}
	}
	
	
	/** Add telephony listener **/
	public static void addTelephonyListener(int[] _keyList){
		
		for(int key:_keyList){
			// register telephony listener
			TelephonyListener lstnr = new TelephonyListener();
			telephonyManager.listen(lstnr, key);
			telephonyListeners.put(key,lstnr);
			}

	}
	
	
	
	/** Remove sensor listener **/
	public static void removeSensorListener(int _key){
		try{
			sensor_manager.unregisterListener(sensorListeners.get(_key));
			sensorListeners.remove(_key);
		}catch(NullPointerException e){
			Log.e("ListenerManager","removeSensorListener: Listener not in list.");
		}
	}
	
	
	/** Remove telephony listener **/
	public static void removeTelephonyListener(int _key){
		try{
			telephonyManager.listen(telephonyListeners.get(_key),PhoneStateListener.LISTEN_NONE);
			telephonyListeners.remove(_key);
		}catch(NullPointerException e){
			Log.v("ListenerManager","removeTelephonyListener: Listener not in list.");
		}
	}
	
	
	
	/** Remove all sensor listeners **/
	public static void removeAllSensorListener(){
		Enumeration<Integer> e = sensorListeners.keys();
		while(e.hasMoreElements())
			removeSensorListener((Integer)e.nextElement());	
	}
	
	
	/** Remove all telephony listeners **/
	public static void removeAllTelephonyListener(){
		Enumeration<Integer> e = telephonyListeners.keys();
		while(e.hasMoreElements())
			removeTelephonyListener((Integer)e.nextElement());	
	}
	
}
